/**
 * WebSocket (SignalR) React Hooks
 */

import { useEffect, useCallback, useState, useRef } from 'react'
import {
  signalRService,
  HubEvent,
  type TaskLogData,
  type TaskStatusData,
  type NodeStatusData,
} from '@/utils/websocket'

/**
 * 使用 SignalR 连接
 */
export function useSignalR() {
  const [isConnected, setIsConnected] = useState(false)
  const [isConnecting, setIsConnecting] = useState(false)

  useEffect(() => {
    const connect = async () => {
      if (signalRService.isConnected()) {
        setIsConnected(true)
        return
      }

      setIsConnecting(true)
      try {
        await signalRService.connect()
        setIsConnected(true)
      } catch (error) {
        console.error('SignalR connection failed:', error)
        setIsConnected(false)
      } finally {
        setIsConnecting(false)
      }
    }

    connect()

    // 监听连接状态变化
    const handleReconnected = () => setIsConnected(true)
    const handleDisconnect = () => setIsConnected(false)

    signalRService.on('reconnected', handleReconnected)
    signalRService.on('disconnect', handleDisconnect)

    return () => {
      signalRService.off('reconnected', handleReconnected)
      signalRService.off('disconnect', handleDisconnect)
    }
  }, [])

  return { isConnected, isConnecting }
}

/**
 * 订阅任务日志
 */
export function useTaskLogs(taskId: number | null) {
  const [logs, setLogs] = useState<TaskLogData[]>([])
  const logsRef = useRef<TaskLogData[]>([])

  useEffect(() => {
    if (!taskId) return

    const handleLog = (logData: TaskLogData) => {
      if (logData.taskId === taskId) {
        const newLogs = [...logsRef.current, logData]
        logsRef.current = newLogs
        setLogs(newLogs)
      }
    }

    // 订阅日志事件
    signalRService.on(HubEvent.RECEIVE_TASK_LOG, handleLog)

    // 订阅任务日志
    signalRService.subscribeTaskLogs(taskId).catch((error) => {
      console.error('Failed to subscribe task logs:', error)
    })

    return () => {
      signalRService.off(HubEvent.RECEIVE_TASK_LOG, handleLog)
      signalRService.unsubscribeTaskLogs(taskId).catch((error) => {
        console.error('Failed to unsubscribe task logs:', error)
      })
    }
  }, [taskId])

  const clearLogs = useCallback(() => {
    logsRef.current = []
    setLogs([])
  }, [])

  return { logs, clearLogs }
}

/**
 * 订阅任务状态
 */
export function useTaskStatus(pipelineInstanceId: number | null) {
  const [status, setStatus] = useState<TaskStatusData | null>(null)

  useEffect(() => {
    if (!pipelineInstanceId) return

    const handleStatus = (statusData: TaskStatusData) => {
      if (statusData.pipelineInstanceId === pipelineInstanceId) {
        setStatus(statusData)
      }
    }

    // 订阅状态事件
    signalRService.on(HubEvent.RECEIVE_TASK_STATUS, handleStatus)

    // 订阅任务状态
    signalRService.subscribeTaskStatus(pipelineInstanceId).catch((error) => {
      console.error('Failed to subscribe task status:', error)
    })

    return () => {
      signalRService.off(HubEvent.RECEIVE_TASK_STATUS, handleStatus)
      signalRService.unsubscribeTaskStatus(pipelineInstanceId).catch((error) => {
        console.error('Failed to unsubscribe task status:', error)
      })
    }
  }, [pipelineInstanceId])

  return status
}

/**
 * 订阅流水线实例(日志+状态)
 */
export function usePipelineInstance(pipelineInstanceId: number | null) {
  const [logs, setLogs] = useState<TaskLogData[]>([])
  const [status, setStatus] = useState<TaskStatusData | null>(null)
  const logsRef = useRef<TaskLogData[]>([])

  useEffect(() => {
    if (!pipelineInstanceId) return

    const handleLog = (logData: TaskLogData) => {
      if (logData.pipelineInstanceId === pipelineInstanceId) {
        const newLogs = [...logsRef.current, logData]
        logsRef.current = newLogs
        setLogs(newLogs)
      }
    }

    const handleStatus = (statusData: TaskStatusData) => {
      if (statusData.pipelineInstanceId === pipelineInstanceId) {
        setStatus(statusData)
      }
    }

    // 订阅事件
    signalRService.on(HubEvent.RECEIVE_TASK_LOG, handleLog)
    signalRService.on(HubEvent.RECEIVE_TASK_STATUS, handleStatus)

    // 订阅流水线实例
    signalRService.subscribePipelineInstance(pipelineInstanceId).catch((error) => {
      console.error('Failed to subscribe pipeline instance:', error)
    })

    return () => {
      signalRService.off(HubEvent.RECEIVE_TASK_LOG, handleLog)
      signalRService.off(HubEvent.RECEIVE_TASK_STATUS, handleStatus)
      signalRService.unsubscribePipelineInstance(pipelineInstanceId).catch((error) => {
        console.error('Failed to unsubscribe pipeline instance:', error)
      })
    }
  }, [pipelineInstanceId])

  const clearLogs = useCallback(() => {
    logsRef.current = []
    setLogs([])
  }, [])

  return { logs, status, clearLogs }
}

/**
 * 订阅节点状态
 */
export function useNodeStatus() {
  const [nodes, setNodes] = useState<Map<number, NodeStatusData>>(new Map())

  useEffect(() => {
    const handleNodeStatus = (nodeData: NodeStatusData) => {
      setNodes((prev) => {
        const newNodes = new Map(prev)
        newNodes.set(nodeData.nodeId, nodeData)
        return newNodes
      })
    }

    // 订阅节点状态事件
    signalRService.on(HubEvent.RECEIVE_NODE_STATUS, handleNodeStatus)

    // 订阅节点状态
    signalRService.subscribeNodeStatus().catch((error) => {
      console.error('Failed to subscribe node status:', error)
    })

    return () => {
      signalRService.off(HubEvent.RECEIVE_NODE_STATUS, handleNodeStatus)
      signalRService.unsubscribeNodeStatus().catch((error) => {
        console.error('Failed to unsubscribe node status:', error)
      })
    }
  }, [])

  return Array.from(nodes.values())
}
